/**
 * @description 地球半径
 */
var EARTH_RADIUS = 6378.137

/**
 * @description 规则协议
 */
const protocol = {
    "checkMobile": function(val) { // 检查手机号码
        var rule = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/; // 2018新型手机号正则表达式
        return rule.test(val);
    },
    "checkEmail": function(val) { // 检查email地址
        let email = val || '';
        return (email.length > 3 && email.indexOf('@') > -1);
    },
    "checkCardNo": function(val) { // 检查身份证号码
        var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
        return reg.test(val);
    },
    "checkChinese": function(val) { // 检查汉字
        var reg = /^[\u4e00-\u9fa5]+$/;
        return reg.test(val);
    }
};

/**
 * @description 常用工具
 * @author zhiyuan Liang
 * @since 2018/05/03
 */
const utils = {

    /**
     * @description 校验检查[手机号码,email地址,身份证号码,汉字等](策略模式)
     */
    check: {
        protocolContent: {
            protocolContent(type, val) {
                return protocol[type](val);
            }
        }
    },

    /**
     * @description 将url与参数键值对拼接为最终的url
     * @param {String} url url
     * @param {object} params 键值对参数对象
     */
    urlByAppendingParams(url, params) {
        let result = url
        if (result.substr(result.length - 1) != '?') {
            result = result + `?`
        }

        for (let key in params) {
            let value = params[key]
            result += `${encodeURIComponent(key)}=${encodeURIComponent(value)}&`
        }

        result = result.substring(0, result.length - 1)
        return result
    },

    /**
     * @description 检查email地址
     * @param {String} email email
     */
    checkEmail(email) {
        email = email || '';
        return (email.length > 3 && email.indexOf('@') > -1);
    },

    /**
     * @description 隐藏手机号
     * @param {Number} mobile 手机号
     */
    hideMobile(mobile) {
        if (mobile.length > 7) {
            var new_mobile = mobile.substr(0, 3) + '****' + mobile.substr(7)
        }
        return new_mobile
    },

    /**
     * @description 隐藏邮箱
     * @param {String} email
     */
    hideEmail(email) {
        if (String(email).indexOf('@') > 0) {
            var str = email.split('@'),
                _s = '';
            if (str[0].length > 3) {
                for (var i = 0; i < str[0].length - 3; i++) {
                    _s += '*';
                }
            }
            var new_email = str[0].substr(0, 3) + _s + '@' + str[1]
        }
        return new_email
    },

    /**
     * @description 检查手机号码
     * @param {Number} mobile 手机号码
     */
    checkMobile(mobile) {
        mobile = mobile || '';
        var rule = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/; // 2018新型手机号正则表达式
        return rule.test(mobile);
    },

    /**
     * @description 去掉字符串前后所有空格
     * @param {String} str
     */
    trim(str) {
        return str.replace(/(^\s*)|(\s*$)/g, "");
    },

    /**
     * 格式化时间戳
     * @param {string} timestamp 时间戳
     */
    timestampFormat(timestamp) {
        function zeroize(num) {
            return (String(num).length == 1 ? '0' : '') + num;
        }

        var curTimestamp = parseInt(new Date().getTime() / 1000); //当前时间戳
        var timestampDiff = curTimestamp - timestamp; // 参数时间戳与当前时间戳相差秒数

        var curDate = new Date(curTimestamp * 1000); // 当前时间日期对象
        var tmDate = new Date(timestamp * 1000); // 参数时间戳转换成的日期对象

        var Y = tmDate.getFullYear(),
            m = tmDate.getMonth() + 1,
            d = tmDate.getDate();
        var H = tmDate.getHours(),
            i = tmDate.getMinutes(),
            s = tmDate.getSeconds();

        if (timestampDiff < 60) { // 一分钟以内
            return '刚刚';
        } else if (timestampDiff < 3600) { // 一小时前之内
            return Math.floor(timestampDiff / 60) + '分钟前';
        } else if (curDate.getFullYear() == Y && curDate.getMonth() + 1 == m && curDate.getDate() == d) {
            return '今天' + zeroize(H) + ':' + zeroize(i);
        } else {
            var newDate = new Date((curTimestamp - 86400) * 1000); // 参数中的时间戳加一天转换成的日期对象
            if (newDate.getFullYear() == Y && newDate.getMonth() + 1 == m && newDate.getDate() == d) {
                return '昨天' + zeroize(H) + ':' + zeroize(i);
            } else if (curDate.getFullYear() == Y) {
                return zeroize(m) + '-' + zeroize(d) + ' ' + zeroize(H) + ':' + zeroize(i);
            } else {
                return Y + '-' + zeroize(m) + '-' + zeroize(d) + ' ' + zeroize(H) + ':' + zeroize(i);
            }
        }
    },
    //将时间戳转换成时间格式
    timestampToTime(timestamp) {
        var date = new Date(timestamp); //时间戳为10位需*1000，时间戳为13位的话不需乘1000
        var Y = date.getFullYear() + '-';
        var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
        var D = date.getDate() + ' ';
        var h = date.getHours() + ':';
        var m = date.getMinutes()
            // + ':';
            // var s = date.getSeconds();
        return Y + M + D + h + m;
    },
    /**
     * @description
     * 对Date的扩展，将 Date 转化为指定格式的String
     * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符
     * 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
     * (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
     * (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18
     * @param {Date} date 日期类型
     * @param {string} fmt 格式化的形式
     */
    dateFormat(date, fmt) {
        var o = {
            "M+": date.getMonth() + 1, //月份
            "d+": date.getDate(), //日
            "h+": date.getHours(), //小时
            "m+": date.getMinutes(), //分
            "s+": date.getSeconds(), //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S": date.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    },
    /**
     * 当前时间 day 天后的年月日时分秒
     * @param {*} day 
     */
    fun_date(day) {
        var date1 = new Date(),
            time1 = date1.getFullYear() + "-" + (date1.getMonth() + 1) + "-" + date1.getDate(); //time1表示当前时间
        var date2 = new Date(date1);
        date2.setDate(date1.getDate() + day);
        var time2 = date2.getFullYear() + "-" + (date2.getMonth() + 1) + "-" + date2.getDate();
        return time2;
    },


    /**
     * 判断数组是否为空
     * @param {string} value
     */
    arrayIsEmpty(value) {
        return (Array.isArray(value) && value.length === 0) || (Object.prototype.isPrototypeOf(value) && Object.keys(value).length === 0);
    },

    /**
     * @description 判断字符是否为空
     * @param {String} obj 字符
     */
    charisEmpty(obj) {
        if (typeof obj == 'undefined' || obj == null || obj == '') {
            return true;
        } else {
            return false;
        }
    },

    /**
     * @description 将用角度表示的角转换为近似相等的用弧度表示的角 java Math.toRadians
     * @param {number} d rad
     */
    rad(d) {
        return d * Math.PI / 180.0;
    },

    /**
     * @description 谷歌地图计算两个坐标点的距离
     * @param {number} lng1  经度1
     * @param {number} lat1  纬度1
     * @param {number} lng2  经度2
     * @param {number} lat2  纬度2
     * @return 距离(km) [注意:如果定位失败的话,传入的是两个空值,并且返回0,给予处理]
     */
    getDistance(lng1, lat1, lng2, lat2) {
        if (lng1 == '' && lat1 == '') {
            return 0; // 如果定位失败的话,传入的是两个空值,并且返回0,给予处理
        }
        if ((lng2 == null || lng2 == '') && (lat2 == null || lat2 == '')) {
            return 0; // 如果定位失败的话,传入的是两个空值,并且返回0,给予处理
        }
        var radLat1 = this.rad(lat1);
        var radLat2 = this.rad(lat2);
        var a = radLat1 - radLat2;
        var b = this.rad(lng1) - this.rad(lng2);
        var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
            Math.cos(radLat1) * Math.cos(radLat2) *
            Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        // s = Math.round(s * 10000) / 10000; // 精确到小数点后四位
        s = (Math.round(s * 10000) / 10000).toFixed(2); // 保留两位小数
        return s;
    },

    /**
     * @description 格式化资金方向[0 来账 1 往账]
     * @param {number} num 0/false 来账 1/true 往账
     */
    directionFormat(num) {
        let str
        switch (num) {
            case 0 || false:
                str = '<span style="color:#fcb816">+</span>'
                break
            case 1 || true:
                str = '<span style="color:#000000">-</span>'
                break
            default:
                str = ''
                break
        }
        return str
    },

    /**
     * @description 小数点后面不足n位数补0
     * @param {number} value 数值
     * @param {number} num 补零位数
     */
    formatNumber(value, num) {
        var a, b, c, i;
        a = value.toString();
        b = a.indexOf(".");
        c = a.length;
        if (num == 0) {
            if (b != -1) {
                a = a.substring(0, b);
            }
        } else { // 如果没有小数点
            if (b == -1) {
                a = a + ".";
                for (i = 1; i <= num; i++) {
                    a = a + "0";
                }
            } else { // 有小数点,超出位数自动截取,否则补0
                a = a.substring(0, b + num + 1);
                for (i = c; i <= b + num; i++) {
                    a = a + "0";
                }
            }
        }
        return a;
    },

    /**
     * @description 生成全局唯一标识符UUID
     */
    uuid() {
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
        // s[8] = s[13] = s[18] = s[23] = "-"; // ios/android端mid有‘-’识别不出来,暂时需要将‘-’隐藏起来
        s[8] = s[13] = s[18] = s[23] = "";

        var uuid = s.join("");
        return uuid;
    },

    /**
     * @description badge图标上的数字大于`limit`,则显示`limit`+
     * @param {number} number 消息个数
     * @param {number} limit 限制的个数
     */
    badgeFormat(number, limit) {
        if (number > limit) {
            return limit + '+'
        }
        return number
    },

    /**
     * @description 超过显示的最大长度[30]部分则以...继续显示
     * @param {string} val 文本
     * @param {number} showLength 限制的长度[需要显示最大的长度]
     */
    lengthLimit(val, showLength) {
        if (val.length > showLength) {
            return val.substring(0, showLength) + '...'
        } else {
            return val
        }
    },

    /**
     * @description 兼容方式-版本比较[微信客户端和小程序基础库的版本号风格为 Major.Minor.Patch(主版本号.次版本号.修订号)]
     * @param {string} v1
     * @param {string} v2
     */
    compareVersion(v1, v2) {
        v1 = v1.split('.')
        v2 = v2.split('.')
        var len = Math.max(v1.length, v2.length)

        while (v1.length < len) {
            v1.push('0')
        }
        while (v2.length < len) {
            v2.push('0')
        }

        for (var i = 0; i < len; i++) {
            var num1 = parseInt(v1[i])
            var num2 = parseInt(v2[i])

            if (num1 > num2) {
                return 1
            } else if (num1 < num2) {
                return -1
            }
        }

        return 0
    },

    /**
     * 得到ref对象
     * @param {string} id
     */
    getRef(id) {
        const components = this.$children;
        let component = false;
        components.forEach(element => {
            if (element.id === id) {
                component = element;
            }
        });
        return component;
    },

    //制保留2位小数，如：2，会在2后面补上00.即2.00
    toDecimal(x) {
        var f = parseFloat(x);
        if (isNaN(f)) {
            return false;
        }
        var f = Math.round(x * 100) / 100;
        var s = f.toString();
        var rs = s.indexOf('.');
        if (rs < 0) {
            rs = s.length;
            s += '.';
        }
        while (s.length <= rs + 2) {
            s += '0';
        }
        return s;
    },

    // 时间格式化输出，如11:03 25:19 每1s都会调用一次
    dateformat(micro_second, t = 0) {
        // 总秒数
        var second = Math.floor(micro_second / 1000);
        // 天数
        var day = Math.floor(second / 3600 / 24);
        // 小时
        var hr = Math.floor(second / 3600 % 24);
        // 分钟
        var min = Math.floor(second / 60 % 60);
        // 秒
        var sec = Math.floor(second % 60);
        if (t == 0) {
            return day + ":" + hr + ":" + min + ":" + sec;
        } else {
            return "0" + ":" + hr + ":" + min + ":" + sec;
        }
        // if (t == 0) {
        //   return day + "天" + hr + "时" + min + "分" + sec + "秒";
        // } else {
        //   return hr + "时" + min + "分" + sec + "秒";
        // }
    },

}

export default utils